/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-28     unknow       copy by STemwin
 */
#ifndef __DRV_KEY_H
#define __DRV_KEY_H
#include <rtthread.h>
#include "rtdevice.h"
#include <drv_common.h>

/**
 * key scan config 
 */
#define DEBOUNCE_TIME       (10)        // 消抖时间
#define KEY_SCAN_TIME       (50)        // 按键状态扫描时间
#define STOP_PRESS_TH       (500)       // 停止检测按键阈值时间，也就是连续按的最大间隔，要是 KEY_SCAN_TIME 的整数倍
#define LONG_PRESS_TH       (800)       // 长按检测阈值时间，要是 KEY_SCAN_TIME 的整数倍，需大于 STOP_PRESS_TH 

#define KEY_SCAN_BY_TIMER   (0)         // 定时器处理按键扫描，开销少
#define KEY_SCAN_BY_THREAD  (1)         // 线程处理按键扫描
#define KEY_SCAN_ENTITY KEY_SCAN_BY_TIMER

/**
 * key message 
 */
struct key_press_message
{
    uint8_t key_id;                     // 按键ID
    uint8_t state;                      // 按键状态
    uint8_t press_type;                 // 按下类型，长按或者连续按，看 key press type
    uint16_t long_time;                 // 长按时间，单位 KEY_SCAN_TIME
    uint16_t series_times;              // 连续按，按键次数
};

/**
 * key inspect struct
 */
struct key_inspect 
{
    int16_t press_times;                // 按下次数，-1为长按
    uint16_t null_times;                // 扫描空按周期数
    uint16_t long_times;                // 扫描长按周期数
    uint16_t cur_state : 1;             // 当前状态
    uint16_t prev_state : 1;            // 上个周期状态
    uint16_t press_flag : 2;            // 扫描标志，看 key scan status
    uint16_t long_flag : 1;             // 长按标志
    uint16_t press_state : 1;           // 扫描按下状态
};

/**
 * key state
 */
struct key_state 
{
    struct key_press_message message;
    struct key_inspect inspect;
};

/**
 * key device 
 */
struct drv_key_device
{
    struct rt_device parent;

    void (*press_handle)(uint8_t key_id);
    void (*realese_handle)(uint8_t key_id);
    void (*msg_handle)(struct key_press_message message);
};

/**
 * key id
 */
#define KEY_ID_UP           (0)
#define KEY_ID_DOWN         (1)
#define KEY_ID_LEFT         (2)
#define KEY_ID_RIGHT        (3)
#define KEY_ID_MAX          (4)

/**
 * key scan status 
 */
#define KEY_SCAN_NULL       (0)		// 没有按键按下
#define KEY_SCAN_PRESS      (1)		// 有按键按下
#define KEY_SCAN_DEBOUNCE   (2)	    // 消抖

/**
 * key press type 
 */
#define KEY_PRESS_NULL      (0)
#define KEY_PRESS_LONG      (1)
#define KEY_PRESS_SERIES    (2)

/**
 * key device control command
 */
#define KEY_CTRL_SET_PRESS_HANDLE           (0)  
#define KEY_CTRL_SET_RELEASE_HANDLE         (1) 
#define KEY_CTRL_SET_MSG_HANDLE             (2)
#define KEY_CTRL_GET_KEY_STATE              (3)

#endif
